/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package JFreeChartExtensions.chartextensions.inset;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import JFreeChartExtensions.chartextensions.utils.Inset;
import JFreeChartExtensions.chartextensions.utils.InsetChartPanel;
import JFreeChartExtensions.Collections.DatasetCollection;
import JFreeChartExtensions.ExtendableChartPanel;
import JFreeChartExtensions.chartextensions.zooming.ChartZoomingManager;
import JFreeChartExtensions.events.ChartChangedEvent;
import JFreeChartExtensions.events.ChartEventPropertiesNames;
import JFreeChartExtensions.events.SeriesChangedEvent;
import JFreeChartExtensions.listeners.IChartChangedListener;
import JFreeChartExtensions.listeners.ISeriesChangedListener;
import JFreeChartExtensions.renderers.XYErrorRendererExtended;
import java.util.HashMap;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeEventType;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.plot.XYPlot;

/**
 *
 * @author Nobody
 */
public class ChartInsetManager extends ChartZoomingManager implements ChartChangeListener, ISeriesChangedListener, IChartChangedListener {

    private void handleAxisChangeEvent(HashMap<ChartEventPropertiesNames, Object> map) throws CloneNotSupportedException {

        Integer axisIndex = (Integer) map.get(ChartEventPropertiesNames.AXIS_INDEX);
        ValueAxis axis = (ValueAxis) map.get(ChartEventPropertiesNames.SENDER);
        String axisType = (String) map.get(ChartEventPropertiesNames.AXIS_TYPE_NAME);

        if (axisType.equals("Domain")) {
            miniatureChart.getXYPlot().setDomainAxis(axisIndex, axis);
        //    lastDomainAxis = (ValueAxis) axis.clone();
        } else if (axisType.equals("Range")) {
            miniatureChart.getXYPlot().setRangeAxis(axisIndex, axis);
          //  lastRangeAxis = (ValueAxis) axis.clone();
        }
    }

    private void handleRendererChangeEvent(HashMap<ChartEventPropertiesNames, Object> map) {
        XYErrorRendererExtended renderer = (XYErrorRendererExtended) map.get(ChartEventPropertiesNames.SENDER);
        Integer datsetNumber = (Integer) map.get(ChartEventPropertiesNames.DATASET_INDEX);
        miniatureChart.getXYPlot().setRenderer(datsetNumber, renderer);
    }

    @Override
    public void chartChanged(ChartChangedEvent event) {

        HashMap<ChartEventPropertiesNames, Object> map = event.getEventProperties();
        if (map.get(ChartEventPropertiesNames.SENDER) instanceof XYPlot) {
            mapDatasetToAxis(map);
        } else if (map.get(ChartEventPropertiesNames.AXIS_TYPE_NAME).equals("Range")
                || map.get(ChartEventPropertiesNames.AXIS_TYPE_NAME).equals("Domain")) {
            try {
                handleAxisChangeEvent(map);
            } catch (CloneNotSupportedException ex) {
                //shouldn't happen
            }
        } else if (map.get(ChartEventPropertiesNames.SENDER) instanceof XYErrorRendererExtended) {
            handleRendererChangeEvent(map);
        }

        inset.getChartPanel().updateUI();
    }
    private JFreeChart miniatureChart;
    private ChartPanel chartPanel;
    private InsetChartPanel insetChartPanel;

    public InsetChartPanel getInsetChartPanel() {
        return insetChartPanel;
    }
    private Inset inset;

    public Inset getInset() {
        return inset;
    }
    private boolean onAir = false;
    private boolean showFitSeries = false;

    public boolean isShowFitSeries() {
        return showFitSeries;
    }

    public void setShowFitSeries(boolean showFitSeries) {
        if (showFitSeries != this.showFitSeries) {
            updateCollection(showFitSeries);
        }
        this.showFitSeries = showFitSeries;
    }

    @Override
    public void register(ChartPanel chartPanel) {
        super.register(chartPanel);
        JFreeChart chart = chartPanel.getChart();
        chart.addChangeListener(this);
        ((ExtendableChartPanel) chartPanel).addChartChangedListener(this);
    }

    @Override
    public void unregister() {
        super.unregister();
        chartPanel.getChart().removeChangeListener(this);
        ((ExtendableChartPanel) chartPanel).removeChartChangedListener(this);
    }

    public ChartInsetManager(ChartPanel chartPanel, Inset inset, InsetChartPanel insetChartPanel) {
       // try {
            this.insetChartPanel = insetChartPanel;
            this.inset = inset;
            JFreeChart chart = chartPanel.getChart();
            this.chartPanel = chartPanel;
            this.miniatureChart = inset.getChartPanel().getChart();
         //   this.lastDomainAxis = (ValueAxis) chart.getXYPlot().getDomainAxis().clone();
          //  this.lastRangeAxis = (ValueAxis) chart.getXYPlot().getRangeAxis().clone();
            ((ExtendableChartPanel) chartPanel).getDatasetCollection().addSeriesAddedListener(this);
     /*   } catch (CloneNotSupportedException ex) {
            Logger.getLogger(ChartInsetManager.class.getName()).log(Level.SEVERE, null, ex);
        }*/
    }

    public void setInsetChartPanel(InsetChartPanel insetChartPanel) {
        this.insetChartPanel = insetChartPanel;
    }

    public void restoreZoom(ChartPanel chartPanel) {
        if (super.zoomFactor == 0) {
            return;
        }
        int width = chartPanel.getMaximumDrawWidth() - chartPanel.getMinimumDrawWidth();
        int height = chartPanel.getMaximumDrawHeight() - chartPanel.getMinimumDrawWidth();

        if (super.zoomFactor > 0) {
            chartPanel.zoomInBoth((width / 2) * super.zoomFactor, (height / 2) * super.zoomFactor);
        } else {
            chartPanel.zoomOutBoth((width / 2) * super.zoomFactor, (height / 2) * super.zoomFactor);
        }
    }


    @Override
    public void chartChanged(ChartChangeEvent cce) {
        if (onAir == true || ignore) {
            return;
        }

        if (cce.getType() == ChartChangeEventType.GENERAL) {
            //try {
                if (cce.getChart() == null) {
                    return;
                }
                if (cce.getChart().getXYPlot() == null) {
                    return;
                }
               /* if (lastDomainAxis.getLowerBound() != cce.getChart().getXYPlot().getDomainAxis().getLowerBound()) {
                    onAir = true;
                    miniatureChart.getXYPlot().setDomainAxis(cce.getChart().getXYPlot().getDomainAxis());
                    miniatureChart.getXYPlot().setRangeAxis(cce.getChart().getXYPlot().getRangeAxis());
                    if (((ExtendableChartPanel) chartPanel).isAxisRevertEnabled()) {
                  //      cce.getChart().getXYPlot().setDomainAxis((ValueAxis) lastDomainAxis.clone());
                   //     cce.getChart().getXYPlot().setRangeAxis((ValueAxis) lastRangeAxis.clone());
                    } else {
                //        this.lastDomainAxis = (ValueAxis) cce.getChart().getXYPlot().getDomainAxis().clone();
                //        this.lastRangeAxis = (ValueAxis) cce.getChart().getXYPlot().getRangeAxis().clone();
                    }
                }*/
                chartPanel.repaint();
               // onAir = false;

          /*  } catch (CloneNotSupportedException ex) {
                Logger.getLogger(InternalFrameWithChart.class.getName()).log(Level.SEVERE, null, ex);
            }*/
        }

    }

    @Override
    public void seriesChanged(SeriesChangedEvent changedEvent) {
        DatasetCollection collection = getInset().getSmallPanel().getDatasetCollection();
        collection.getAllRendererCollections().get(1).setVisibleForAllRegressionSeries(showFitSeries);
    }

    private void updateCollection(boolean showFitSeries) {
        DatasetCollection collection = getInset().getSmallPanel().getDatasetCollection();
        collection.getAllRendererCollections().get(1).setVisibleForAllRegressionSeries(showFitSeries);

    }

    public void setInset(Inset inset) {
        this.inset = inset;
    }

    private void mapDatasetToAxis(HashMap<ChartEventPropertiesNames, Object> map) {
        Integer seriesIndex = (Integer) map.get(ChartEventPropertiesNames.SERIES_INDEX);
        Integer axisIndex = (Integer) map.get(ChartEventPropertiesNames.AXIS_INDEX);
        String axisType = (String) map.get(ChartEventPropertiesNames.AXIS_TYPE_NAME);

        if (axisType.equals("Domain")) {
            getInset().getSmallChart().getXYPlot().mapDatasetToDomainAxis(seriesIndex, axisIndex);
        } else if (axisType.equals("Range")) {
            getInset().getSmallChart().getXYPlot().mapDatasetToRangeAxis(seriesIndex, axisIndex);
        }
        getInset().getChartPanel().updateUI();
    }
}
